package com.premadefood.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.premadefood.common.ErrorCode;
import com.premadefood.domain.Goods;
import com.premadefood.domain.Goodsviewhistory;
import com.premadefood.domain.Storefocus;
import com.premadefood.domain.User;
import com.premadefood.domain.dto.GoodsDTO;
import com.premadefood.domain.vo.GoodsVO;
import com.premadefood.exception.BusinessException;
import com.premadefood.mapper.GoodsMapper;
import com.premadefood.service.GoodsService;
import com.premadefood.service.GoodsviewhistoryService;
import com.premadefood.service.StorefocusService;
import com.premadefood.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 23854
 * @description 针对表【goods】的数据库操作Service实现
 * @createDate 2024-02-27 16:10:49
 */
@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods>
        implements GoodsService {

    @Resource
    private UserService userService;

    @Resource
    private StorefocusService storefocusService;

    @Resource
    private GoodsviewhistoryService goodsviewhistoryService;

    /**
     * 根据搜索词条搜索商品
     *
     * @param searchContext
     * @return
     */
    @Override
    public List<GoodsVO> searchGoods(String searchContext) {
        if (StringUtils.isBlank(searchContext)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "商品搜索内容不能为空");
        }
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name", searchContext).or().like("storeName", searchContext);
        List<Goods> goodsList = this.list(queryWrapper);

        return goodsList.stream().map(item -> {
            GoodsVO goodsVO = new GoodsVO();
            BeanUtils.copyProperties(item, goodsVO);
            return goodsVO;
        }).collect(Collectors.toList());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean focusGoods(Integer goodsId, HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        String goodFocus = loginUser.getGoodFocus();
        Gson gson = new Gson();
        Set<Integer> favoriteGoodsIds = gson.fromJson(goodFocus,
                new TypeToken<Set<Integer>>() {
                }.getType());
        favoriteGoodsIds = Optional.ofNullable(favoriteGoodsIds).orElse(new HashSet<>());
        favoriteGoodsIds.add(goodsId);
        String favoriteGoodsIdsJson = gson.toJson(favoriteGoodsIds);
        loginUser.setGoodFocus(favoriteGoodsIdsJson);
        boolean save = userService.updateById(loginUser);
        if (!save) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "修改失败");
        }

        return true;

    }

    /**
     * 点击查看商品详情
     * @param goodsId
     * @param request
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public GoodsDTO showDetail(Integer goodsId, HttpServletRequest request) {
        Goods goods = this.getById(goodsId);
        User loginUser = userService.getLoginUser(request);
        String goodFocus = loginUser.getGoodFocus();
        Gson gson = new Gson();
        Set<Integer> favoriteGoodsIds = gson.fromJson(goodFocus,
                new TypeToken<Set<Integer>>() {
                }.getType());
        GoodsDTO goodsDTO = new GoodsDTO();
        BeanUtils.copyProperties(goods, goodsDTO);
        //商品查看历史表新增记录
        //先查询是否已有查看记录，如果有记录，则刷新它的更新时间
        QueryWrapper<Goodsviewhistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId",loginUser.getId()).eq("goodsId",goodsId);
        Goodsviewhistory goodsviewhistory = goodsviewhistoryService.getOne(queryWrapper);

        if(goodsviewhistory != null) {
            goodsviewhistory.setUpdateTime(new Date());
            goodsviewhistoryService.updateById(goodsviewhistory);
        }
        //如果没有记录则新增一条记录
        else {
            Goodsviewhistory newGoodsviewhistory = new Goodsviewhistory();
            newGoodsviewhistory.setUserId(loginUser.getId());
            newGoodsviewhistory.setGoodsId(goodsDTO.getId());
            goodsviewhistoryService.save(newGoodsviewhistory);
        }

        //是否已收藏该商品
        goodsDTO.setIsFavorite(favoriteGoodsIds.contains(goodsId));
        String storeName = goods.getStoreName();
        boolean hasFollowed = hasFollowed(storeName, loginUser.getId());
        goodsDTO.setIsFollowStore(hasFollowed);
        return goodsDTO;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean focusStore(String storeName, HttpServletRequest request) {
        if (StringUtils.isBlank(storeName)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "商品名称不能为空");
        }
        User loginUser = userService.getLoginUser(request);
        Integer userId = loginUser.getId();
        //如果该用户已经收藏了,则为取消关注
        boolean hasFollowed = hasFollowed(storeName, userId);

        if (hasFollowed) {
            QueryWrapper<Storefocus> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("storeName", storeName)
                    .eq("userId", userId);
            boolean remove = storefocusService.remove(queryWrapper);
            if (!remove) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        }
        //没有收藏，那就插入该数据进入收藏表
        else {
            Storefocus storefocus = new Storefocus();
            storefocus.setStoreName(storeName);
            storefocus.setUserId(userId);
            boolean save = storefocusService.save(storefocus);
            if (!save) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
        }
        return true;

    }

    @Override
    public List<GoodsVO> showTimeNew(long pageNum) {
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("isTimeNew",1);
        return getGoodsVOS(pageNum, queryWrapper);

    }

    @Override
    public List<GoodsVO> showSecondSale(long pageNum) {
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("isSecondSale",1);
        return getGoodsVOS(pageNum, queryWrapper);
    }

    /**
     * 需要分页的转换GoodsVO
     * @param pageNum
     * @param queryWrapper
     * @return
     */
    public List<GoodsVO> getGoodsVOS(long pageNum, QueryWrapper<Goods> queryWrapper) {
        Page<Goods> page = this.page(new Page<>(pageNum, 15), queryWrapper);
        return page.getRecords().stream().map(item ->
        {
            GoodsVO goodsVO = new GoodsVO();
            BeanUtils.copyProperties(item, goodsVO);
            return goodsVO;
        }).collect(Collectors.toList());
    }

    /**
     * 无需分页的转换GoodsVO
     * @param queryWrapper
     * @return
     */
    public List<GoodsVO> getGoodsVOS(QueryWrapper<Goods> queryWrapper) {
        List<Goods> list = this.list(queryWrapper);
        return list.stream().map(item ->
        {
            GoodsVO goodsVO = new GoodsVO();
            BeanUtils.copyProperties(item, goodsVO);
            return goodsVO;
        }).collect(Collectors.toList());
    }

    /**
     * 是否已收藏该店铺
     *
     * @param storeName
     * @param userId
     * @return
     */
    private boolean hasFollowed(String storeName, Integer userId) {
        QueryWrapper<Storefocus> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("storeName", storeName)
                .eq("userId", userId);
        int count = storefocusService.count(queryWrapper);
        //如果查出来数量不为0，则说明已收藏了该店铺
        boolean hasFollowed = false;
        if (count != 0) {
            hasFollowed = true;
        }
        return hasFollowed;
    }
}




